﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Drawing;

using Toom.CellularAutomata.Model;
using Toom.CellularAutomata.Parser;
using Toom.CellularAutomata.Debug;
using Toom.CellularAutomata.Common;


namespace Toom.CellularAutomata.GUI
{
	public class CARunner
	{

		#region Ctor

		public CARunner( FormCAMAIN parent )
		{
			this.formParent = parent;
		}

		#endregion


		#region Vars

		public bool workerRunning = false;
		public bool workerStopRequested = false;

		//public string workerSavedButtonTitle;
		public Color workerSavedBGColor;
		public Color workerSavedFGColor;

		public double workerSleepInSec=0.01;
		public CAGameType game;
		public CARule customRule;

		public FormCAMAIN formParent;
		public Thread thread = null;

		public int nrCycles = 0;
		public long startTime = 0;

		#endregion


		#region BG Runner Method

		public void RunUpdatesToField()
		{
			formParent.formField.glField.MakeCurrent();

			int workerSleepInMs = (int)( workerSleepInSec*1000 );

			CATimer timer = new CATimer(false);
			startTime = DateTime.Now.Ticks;
			nrCycles = 0;

			while ( ! workerStopRequested )
			{
				// make sure everyone knows we are running the thread
				workerRunning = true;
				nrCycles++;

				
				// transform
				timer.Start();
				if ( game == CAGameType.CUSTOM )
					formParent.field.DoTransform( customRule, CASettings.Optimization );
				else
					formParent.field.DoTransform( game, CASettings.Optimization );

				double t1 = timer.GetSAndReset();
				formParent.perf.UpdateTracker( "calc", t1 );

				// display
				double avgCyclesPS = (double)nrCycles * 10000000 / ( DateTime.Now.Ticks - startTime ); 
				formParent.formField.DisplayFieldAsImage( avgCyclesPS );

				// check if field is all zeros
				if ( formParent.field.IsAllZero() )
				{
					workerStopRequested = true;
				}

				Thread.Sleep( workerSleepInMs );
			}

			// we are stopping, so setting status vars accordingly
			workerRunning = false;
			workerStopRequested = false;

			formParent.formField.glField.Context.MakeCurrent(null);

			//formParent.HandleWorkerExited();

		}

		#endregion

	}
}
